package com.aube.mis.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.aube.mis.dto.InfoDTO;
import com.aube.mis.dto.ItemPositionDTO;
import com.aube.mis.dto.MulticameraDTO;
import com.aube.mis.dto.MulticameraVideoDTO;
import com.aube.mis.dto.QaDTO;
import com.aube.mis.dto.QaOptionDTO;
import com.aube.mis.dto.QuizDTO;
import com.aube.mis.dto.QuizOptionDTO;
import com.aube.mis.dto.RelatedCallbackDTO;
import com.aube.mis.dto.TimelineBaseDTO;
import com.aube.mis.dto.TimelineHighlightDTO;
import com.aube.mis.dto.TimelineItemDTO;
import com.aube.mis.dto.TimelineItemIdentifyDTO;
import com.aube.mis.dto.TimelineItemLocationDTO;
import com.aube.mis.dto.VideoDTO;
import com.aube.mis.dto.VideoThemeDTO;
import com.aube.mis.dto.VoteDTO;
import com.aube.mis.dto.VoteOptionDTO;
import com.aube.mis.dto.VsDTO;
import com.aube.mis.service.ResourceService;
import com.aube.mis.service.ShowService;
import com.aube.mis.service.ShowSettingService;
import com.aube.mis.service.ThemeService;
import com.aube.mis.service.TimelineService;
import com.aube.mis.util.JsonUtil;

@Controller
@RequestMapping(value = "/timeline")
public class TimelineController extends AbstractController {

	private static Logger log = LoggerFactory.getLogger(TimelineController.class);

	@Resource
	ShowService showService;

	@Resource
	ShowSettingService showSettingService;

	@Resource
	ResourceService resourceService;

	@Resource
	TimelineService timelineService;

	@Resource
	ThemeService themeService;

	@RequestMapping(value = "/edit")
	public <T extends TimelineBaseDTO> String timelineEdit(HttpServletResponse response, ModelMap map, String videoId, String type, @ModelAttribute RelatedCallbackDTO relatedCallbackDTO) throws Throwable {
		if("1".equals(relatedCallbackDTO.getIsRelatedCallback())) {
			if("theme".equals(relatedCallbackDTO.getRelatedType())) {
				themeService.updateVideoTheme(relatedCallbackDTO.getSourceId(), relatedCallbackDTO.getSelectedRelatedIds());
			}
		}
		List<T> timelineList = timelineService.getTimelineList(getShowId(), videoId, null);
		VideoDTO videoDetail = resourceService.getVideoDetail(getShowId(), videoId);
		VideoThemeDTO theme = themeService.getVideoThemeDetailByVideo(getShowId(), videoId);
		map.put("theme", theme);
		map.put("timelineListJson", JsonUtil.toJson(timelineList));
		map.put("type", type);
		map.put("videoId", videoId);
		map.put("videoDetail", videoDetail);
		map.put("relatedCallback", relatedCallbackDTO);
		if (StringUtils.isEmpty(theme.getThemeCode()) || Thread.currentThread().getContextClassLoader().getResource("META-INF/webapp/WEB-INF/view/timeline/theme/" + theme.getThemeCode()) == null) {
			map.put("themeCode", "default");
		} else {
			map.put("themeCode", theme.getThemeCode());
		}
		map.put("themeCode", "FamiliarTaste");
		return "/timeline/edit";
	}

	@RequestMapping(value = "/setting", method = RequestMethod.GET)
	public String timelineSetting(HttpServletResponse response, ModelMap map, String videoId) throws Throwable {
		map.put("videoId", videoId);
		return "/timeline/setting.page";
	}

	@RequestMapping(value = "/entity/preview")
	public String entityPreview(ModelMap map, String isDraggable, String timelineId, String type, String themeCode) throws Throwable {
		map.put("isDraggable", isDraggable);
		map.put("timelineId", timelineId);
		map.put("themeCode", themeCode);
		return "/timeline/" + type.toLowerCase() + "/preview.page";
	}

	@RequestMapping(value = "/entity/edit", method = RequestMethod.GET)
	public String entityEdit(HttpServletResponse response, ModelMap map, String timelineId, String videoId, Boolean isEdit, String type, String selectedId) throws Throwable {
		if (isEdit != null && isEdit) {
			TimelineBaseDTO timelineDetail = timelineService.getTimelineDetail(timelineId, videoId);
			type = timelineDetail.getType();
			map.put("timelineDetail", timelineDetail);
		} else {
			isEdit = false;
		}
		VideoThemeDTO theme = themeService.getVideoThemeDetailByVideo(getShowId(), videoId);
		map.put("theme", theme);
		map.put("videoId", videoId);
		map.put("isEdit", isEdit);
		map.put("selectedId", selectedId);
		return "/timeline/" + type.toLowerCase() + "/edit.page";
	}

	@RequestMapping(value = "/entity/delete.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public String entityDelete(String timelineId) throws Throwable {
		timelineService.deleteTimeline(timelineId);
		return this.createSuccessResponse();
	}

	@RequestMapping(value = "/vs/edit.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public String vsEditAjax(@ModelAttribute VsDTO vsDTO) throws Throwable {
		timelineService.editVs(vsDTO);
		return this.createSuccessResponse();
	}

	@RequestMapping(value = "/qa/edit.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public String qaEditAjax(@ModelAttribute QaDTO qaDTO) throws Throwable {
		List<QaOptionDTO> optionList = qaDTO.getOptionList();
		for (ListIterator<QaOptionDTO> listIterator = optionList.listIterator(); listIterator.hasNext();) {
			int index = listIterator.nextIndex();
			QaOptionDTO dto = listIterator.next();
			if (qaDTO.getAnswerIndex() != null && index == qaDTO.getAnswerIndex()) {
				dto.setIsAnswer("Y");
			} else {
				dto.setIsAnswer("N");
			}
			if (StringUtils.isEmpty(dto.getOptionValue())) {
				listIterator.remove();
			}
		}
		timelineService.editQa(qaDTO);
		return this.createSuccessResponse();
	}

	@RequestMapping(value = "/vote/edit.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public String voteEditAjax(@ModelAttribute VoteDTO voteDTO) throws Throwable {
		List<VoteOptionDTO> optionList = voteDTO.getOptionList();
		for (Iterator<VoteOptionDTO> iterator = optionList.iterator(); iterator.hasNext();) {
			VoteOptionDTO dto = iterator.next();
			if (StringUtils.isEmpty(dto.getOptionValue())) {
				iterator.remove();
			}
		}
		timelineService.editVote(voteDTO);
		return this.createSuccessResponse();
	}

	@RequestMapping(value = "/info/edit.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public String infoEditAjax(@ModelAttribute InfoDTO infoDTO) throws Throwable {
		timelineService.editInfo(infoDTO);
		return this.createSuccessResponse();
	}


	@RequestMapping(value = "/quiz/edit.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public String quizEditAjax(@ModelAttribute QuizDTO quizDTO) throws Throwable {
		List<QuizOptionDTO> optionList = quizDTO.getOptionList();
		for (ListIterator<QuizOptionDTO> listIterator = optionList.listIterator(); listIterator.hasNext();) {
			int index = listIterator.nextIndex();
			QuizOptionDTO dto = listIterator.next();
			if (quizDTO.getAnswerIndex() != null && index == quizDTO.getAnswerIndex()) {
				dto.setIsAnswer("Y");
			} else {
				dto.setIsAnswer("N");
			}
			if (StringUtils.isEmpty(dto.getOptionValue())) {
				listIterator.remove();
			}
		}
		timelineService.editQuiz(quizDTO);
		return this.createSuccessResponse();
	}

	@RequestMapping(value = "/item/edit.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public String itemEditAjax(@ModelAttribute TimelineItemDTO itemDTO) throws Throwable {
		if(CollectionUtils.isNotEmpty(itemDTO.getRidList())) {
			for (Iterator<String> iterator = itemDTO.getRidList().iterator(); iterator.hasNext();) {
				String rid = iterator.next();
				if (StringUtils.isEmpty(rid)) {
					iterator.remove();
				}
			}
		}
		String timelineId = timelineService.editItem(itemDTO);
		Map<String, Object> dataMap = new HashMap<String, Object>();
		dataMap.put("timelineId", timelineId);
		return this.createSuccessResponse(dataMap);
	}

	@RequestMapping(value = "/item/getIdentifyData.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public String getItemIdentifyData(String videoId, String itemId, String timelineId) throws Throwable {
		TimelineItemIdentifyDTO itemIdentifyData = timelineService.getItemIdentifyData(getShowId(), videoId , itemId, timelineId);
		Map<String, Object> dataMap = new HashMap<String, Object>();
		dataMap.put("itemIdentifyData", itemIdentifyData);
		return this.createSuccessResponse(dataMap);
	}

	@RequestMapping(value = "/item/saveIdentifyData.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public String saveIdentifyData(@ModelAttribute TimelineItemLocationDTO timelineItemLocationDTO, String timelineId, String showId, String videoId, String itemId) throws Throwable {
		timelineService.saveItemIdentifyData(timelineItemLocationDTO, showId, videoId, itemId);
		TimelineItemIdentifyDTO itemIdentifyData = timelineService.getItemIdentifyData(getShowId(), videoId , itemId, timelineId);
		Map<String, Object> dataMap = new HashMap<String, Object>();
		dataMap.put("itemIdentifyData", itemIdentifyData);
		return this.createSuccessResponse(dataMap);
	}

	@RequestMapping(value = "/item/identify.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public String identify(String itemIds, String showId, String videoId) throws Throwable {
		timelineService.identifyItem(Arrays.asList(itemIds.split(",")), showId, videoId);
		return this.createSuccessResponse();
	}

	@RequestMapping(value = "/multicamera/editSub", method = RequestMethod.GET)
	public String editSub(HttpServletResponse response, ModelMap map, String isEdit, String timelineId, String videoId, String rid) {
		map.put("isEdit", isEdit);
		map.put("rid", rid);
		if(StringUtils.isNotEmpty(rid)) {
			MulticameraVideoDTO subMulticameraDetail = timelineService.getSubMulticameraDetail(rid);
			map.put("multicamera", subMulticameraDetail);
			map.put("videoId", subMulticameraDetail.getVideoId());
			map.put("timelineId", subMulticameraDetail.getTimelineId());
		} else {
			map.put("videoId", videoId);
			map.put("timelineId", timelineId);
		}
		return "/timeline/multicamera/editSub.page";
	}

	@RequestMapping(value = "/multicamera/editMain.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public String multicameraEditMainAjax(@ModelAttribute MulticameraDTO multicameraDTO) throws Throwable {
		timelineService.editMainMulticamera(multicameraDTO);
		return this.createSuccessResponse();
	}

	@RequestMapping(value = "/multicamera/editSub.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public String multicameraEditSubAjax(@ModelAttribute MulticameraVideoDTO multicameraVideoDTO) throws Throwable {
		timelineService.editSubMulticamera(multicameraVideoDTO);
		return this.createSuccessResponse();
	}

	@RequestMapping(value = "/multicamera/delete.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public String multicameraDeleteAjax(String rid) throws Throwable {
		timelineService.deleteMulticamera(rid);
		return this.createSuccessResponse();
	}

	@RequestMapping(value = "/list/data.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public <T extends TimelineBaseDTO> String timelineList(String videoId, String type) throws Throwable {
		List<T> timelineList = (List<T>) timelineService.getTimelineList(getShowId(), videoId, type);
		Map<String, Object> dataMap = new HashMap<String, Object>();
		dataMap.put("list", timelineList);
		dataMap.put("total", timelineList.size());
		return this.createSuccessResponse(dataMap);
	}

	@RequestMapping(value = "/highlight/edit.ajax", produces = "text/plain;charset=UTF-8")
	@ResponseBody
	public String highlightEditAjax(@ModelAttribute TimelineHighlightDTO highlightDTO) throws Throwable {
		timelineService.editHighlight(highlightDTO);
		return this.createSuccessResponse();
	}

	@RequestMapping(value = "/optionPopupSetting", method = RequestMethod.GET)
	public String optionPopupSetting(HttpServletResponse response, ModelMap map, String clientType, String picUrl, String optionIndex) throws Throwable {
		map.put("picUrl", picUrl);
		map.put("clientType", clientType);
		map.put("optionIndex", optionIndex);
		return "/timeline/optionPopupSetting.page";
	}
}
